package com.leo.base.mail.service.impl;

import com.leo.base.exception.CustomException;
import com.leo.base.mail.service.IMailService;
import com.leo.base.mail.vo.Mail;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.Objects;

/**
 * @ClassName MailServiceImpl
 * @Description
 * @Author wangss
 * @date 2020.09.23 19:48
 * @Version 1.0
 */
@Slf4j
@Service
public class MailServiceImpl implements IMailService {

    @Value("${spring.mail.username}")
    private String from;

    @Value("${spring.mail.template}")
    private String template;

    @Resource
    private JavaMailSenderImpl mailSender;

    @Resource
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @Async
    @Override
    public Mail sendMail(Mail mail) {
        try {
            //1.检测邮件
            checkMail(mail);
            //2.发送邮件
            sendMimeOrTemplateMail(mail);
            //3.保存邮件
            return saveMail(mail);
        } catch (Exception e) {
            mail.setStatus("fail");
            mail.setError(e.getMessage());
            return mail;
        }
    }

    /**
     * 检测邮件信息类
     *
     * @param mailVo
     */
    private void checkMail(Mail mailVo) {
        if (StringUtils.isEmpty(mailVo.getTo())) {
            log.error("邮件收信人不能为空");
            throw new CustomException("邮件收信人不能为空");
        }
        if (StringUtils.isEmpty(mailVo.getSubject())) {
            log.error("邮件主题不能为空");
            throw new CustomException("邮件主题不能为空");
        }
        if (StringUtils.isEmpty(mailVo.getText()) && CollectionUtils.isEmpty(mailVo.getVariables())) {
            log.error("邮件内容不能为空");
            throw new CustomException("邮件内容不能为空");
        }
    }

    /**
     * 构建复杂邮件信息类或者模板邮件
     *
     * @param mailVo
     */
    private void sendMimeOrTemplateMail(Mail mailVo) {
        try {

            MimeMessageHelper messageHelper = createMimeMessageHelper(mailVo);

            if (CollectionUtils.isEmpty(mailVo.getVariables())) {
                // 邮件内容
                messageHelper.setText(mailVo.getText(), mailVo.isHtml());
            } else {
                Template template = freeMarkerConfigurer.getConfiguration().getTemplate(this.template);
                String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, mailVo.getVariables());
                messageHelper.setText(html, true);
            }

            // 添加邮件附件
            if (ArrayUtils.isNotEmpty(mailVo.getFiles())) {
                for (File file : mailVo.getFiles()) {
                    messageHelper.addAttachment(file.getName(), file);
                }
            }
            // 正式发送邮件
            mailSender.send(messageHelper.getMimeMessage());
            mailVo.setStatus("ok");
            log.info("邮件发送成功");
        } catch (Exception e) {
            log.error("邮件发送异常：[{}]", e.getMessage());
            throw new CustomException(e.getMessage());
        }
    }

    private MimeMessageHelper createMimeMessageHelper(Mail mailVo) {
        try {
            // true表示支持复杂类型
            MimeMessageHelper messageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true);

            if (StringUtils.isNotEmpty(from)) {
                // 邮件发信人从配置项读取
                mailVo.setFrom(from);
            }
            // 邮件发信人
            messageHelper.setFrom(mailVo.getFrom());
            // 邮件收信人
            messageHelper.setTo(mailVo.getTo().split(","));
            // 邮件主题
            messageHelper.setSubject(mailVo.getSubject());
            // 抄送
            if (StringUtils.isNotEmpty(mailVo.getCc())) {
                messageHelper.setCc(mailVo.getCc().split(","));
            }
            // 密送
            if (StringUtils.isNotEmpty(mailVo.getBcc())) {
                messageHelper.setCc(mailVo.getBcc().split(","));
            }
            // 发送时间
            if (Objects.isNull(mailVo.getSentDate())) {
                mailVo.setSentDate(new Date());
                messageHelper.setSentDate(mailVo.getSentDate());
            }
            return messageHelper;
        } catch (Exception e) {
            log.error("创建邮件信息异常：[{}]", e.getMessage());
            throw new CustomException(e.getMessage());
        }
    }

    /**
     * 保存邮件
     *
     * @param mailVo
     * @return
     */
    private Mail saveMail(Mail mailVo) {

        // TODO 将邮件保存到数据库..

        return mailVo;
    }
}
